package com.dragon.app.config.aop;


import com.alibaba.fastjson.JSONObject;
import com.dragon.app.config.annotation.OperationRecord;
import com.dragon.common.util.JwtUtil;
import com.dragon.logical.service.customer.IOperationRecordService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class  OperationRecordAop {

    @Autowired
    IOperationRecordService recordService;


    @Pointcut("@annotation(com.dragon.app.config.annotation.OperationRecord)")
    public void operationRecordPointCut(){

    }


    @AfterReturning(pointcut = "operationRecordPointCut()",returning = "returnValue")
    public void doAfterReturning(JoinPoint joinPoint,Object returnValue)throws IOException{
        handleOperationRecord(joinPoint,returnValue);
    }

    private void handleOperationRecord(JoinPoint joinPoint,Object returnValue)throws IOException{
        OperationRecord operationRecord =  getAnnotation(joinPoint);
        //操作参数
        int actionType = operationRecord.actionType();
        //步骤参数
        int operationType = operationRecord.operationType();

        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        assert sra != null;
        HttpServletRequest request = sra.getRequest();
        Integer id=null;
        Integer adminId = Integer.parseInt(JwtUtil.getAdminId(request));
        String cause = "";
        // 添加
        if(actionType==1){
            //获取项目id
            Map<String,Object> params = getRequestBody(request,joinPoint);
            if(operationType == 1){
                Map<String,Object> result = JSONObject.parseObject(JSONObject.toJSONString(returnValue),Map.class);
                id = (Integer) result.get("data");
            } else {
                id = (Integer) params.get("projectId");
            }
        }
        // 修改
        if(actionType==2){
            Map<String,Object> params = getRequestBody(request,joinPoint);
            if(operationType==1){
                id = (Integer) params.get("id");
            } else {
                id = (Integer) params.get("projectId");
            }
        }
        // 删除
        if(actionType==3){
            if(operationType != 1){
                id = Integer.parseInt(request.getParameter("projectId"));
            } else {
                id = Integer.parseInt(request.getParameter("id"));
            }
        }
        // 审核
        if(actionType==4){
            if(operationType != 1){
                id = Integer.parseInt(request.getParameter("projectId"));
            } else {
                id = Integer.parseInt(request.getParameter("id"));
            }
            cause = request.getParameter("cause");
        }
        //操作记录记录到数据库中
        recordService.addOperationRecord(id,adminId,cause,actionType,operationType);
    }

    /**
     * 是否存在注解，如果存在就获取，不存在则返回null
     * @param joinPoint
     * @return
     */
    private OperationRecord getAnnotation(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            return method.getAnnotation(OperationRecord.class);
        }
        return null;
    }

    /**
     * 获取body里面的参数
     * @param request
     * @param joinPoint
     * @return
     */
    private Map<String,Object> getRequestBody(HttpServletRequest request,JoinPoint joinPoint){
        String param = JSONObject.toJSONString(joinPoint.getArgs())
                .replace("[","")
                .replace("]","")
                .replace("corrlelationId","id");
        Map<String,Object> map = JSONObject.parseObject(param,HashMap.class);
        return map;
    }

}
